-- Dump Instruction Tree --

Dump.Instruction (LABEL .label) (.out) :-
	concat .label "." .out ! #
Dump.Instruction (.inst .op) (.out) :-
	Dump.Operand .op .s,
	concat .inst " " .s .out ! #
Dump.Instruction (.inst .op1 .op2) (.out) :-
	Dump.Operand .op1 .s1,
	Dump.Operand .op2 .s2,
	concat .inst " " .s1 "," .s2 .out ! #
Dump.Instruction .inst (.inst) :- ! #

Dump.Operand (SIZE .size .op) (.out) :-
	Dump.Operand .op .out0,
	select
		(Config.WordSize .size => concat "WORD " .out0 .out)
		(.size = 1 => concat "BYTE " .out0 .out)
		(.size = 2 => concat "D16 " .out0 .out)
		(.size = 4 => concat "D32 " .out0 .out)
		(.size = 8 => concat "D64 " .out0 .out)
	#

Dump.Operand (LABEL .label) (.out) :- -- To process compiler output
	concat "&" .label .out ! #
Dump.Operand (GR .size .r) (.out) :-
	Register .out (GR .size .r) ! #
Dump.Operand (IMM .i) (.out) :-
	concat .i .out ! #
Dump.Operand (MEM .base .index .scale .disp) (.out) :-
	if (.base = $) then (
		.bs = ""
	) else (
		Register .br .base,
		concat .br "+" .bs
	),
	if (.index = $) then (
		.is = ""
	) else (
		Register .ir .index,
		concat .ir "*" .scale "+" .is
	),
	if (.disp = 0) then (
		.ds =  ""
	) else (
		concat .disp "+" .ds
	),
	concat .bs .is .ds .o,
	if (.o = "") then (
		.out = "[0]"
	) else (
		substr .o 0 -1 .o1, -- Reduces the extra "+" symbol
		concat "[" .o1 "]" .out
	) ! #
